package org.example.config.loadBalancer;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;

import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import reactor.core.publisher.Mono;

//@Configuration
public class BLoadBalancerConfiguration {

    @Bean
    public ReactorServiceInstanceLoadBalancer customLoadBalancer(Environment environment,
                                                                 ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        String name = environment.getProperty("spring.application.name");
        return new CustomLoadBalancer(serviceInstanceListSupplierProvider, name);
    }

    static class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
        private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
        private final String serviceId;

        CustomLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
                           String serviceId) {
            this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
            this.serviceId = serviceId;
        }

        //负载均衡器的核心逻辑 负载均衡逻辑是随机选择一个可用的服务实例
        @Override
        public Mono<Response<ServiceInstance>> choose(Request request) {
            ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
            assert supplier != null;
            return supplier.get(request).next().map(serviceInstances -> {
                if (serviceInstances.isEmpty()) {
                    return new EmptyResponse();
                }
                // 自定义负载均衡逻辑 使用随机算法从服务实例列表中选择一个实例。
                int index = (int) (Math.random() * serviceInstances.size());
                // 返回所选服务实例的响应。
                return new DefaultResponse(serviceInstances.get(index));
            });
        }
    }
}
